// ///////////////////////////////////////////
// initialize 
VIEW_FROM_QQ_APP = $("#qq_open_id").val();
DEBUG=0;
THUMB_WIDTH = VIEW_FROM_QQ_APP ? 60 : 60;
THUMB_HEIGHT = VIEW_FROM_QQ_APP ? 60 : 60;
BODY_WIDTH_FROM_QQ = 740;
MAX_FAMILY_BOX_WIDTH = 1200;
THUMB_MARGIN_X = 10;
THUMB_MARGIN_Y = 10;
MAX_HORIZON_CHILD_NUM = 13;
X_LARGE_NUM = 28;
X_MEDIUM_NUM = 18;
NAME_HEIGHT = 15;
NAME_MARGIN_TOP=22;
MEMBER_COUNT=60;
QIN_TREE_MIN_WIDTH = VIEW_FROM_QQ_APP ? 690 : 300;
ASIDE_MIN_WIDTH = 300;
ASIDE_MAX_WIDTH = "100%";
TREE_PADDING = 10;
RELATIVE_LINE_HEIGHT = 50;
BUTTON_WIDTH = 30;
BUTTON_HEIGHT = 15;
BUTTON_MARGIN_X = 5;
BUTTON_MARGIN_Y = 4;
BUTTON_FONT_HEIGHT = 10;
BUTTON_FONT_PADDING_LEFT = 3;
BUTTON_FONT_PADDING_TOP = 2;
BUTTON_FONT_STYLE = BUTTON_FONT_HEIGHT+"px 宋体";
MEMBER_BLOCK_HEIGHT = THUMB_HEIGHT + NAME_HEIGHT + THUMB_MARGIN_Y + NAME_MARGIN_TOP;
RADIUS = 5;
PARENT_RADIUS = 5;
CHILD_RADIUS = 2;
CHILD_POINT_PADDING = 7;
LEVEL = 3;
MAX_MATES = 2;
NAME_STYLE = "normal lighter 10px serif";
NAME_LENGTH = 3;
BASE_LINE = "top";
LINE_STYLE = '#B3614D';
THUMB_OUT_BORDER = "#999999";
ROOT_LINE_WIDTH = 4;
THUMB_BORDER_WIDTH = 2;
MALE_FIGURE = "/Public/Img/male.png";
FEMALE_FIGURE= "/Public/Img/female.png";
COLUMN = 9;
prev_x = 0;
prev_y = 0;

elements = [];
buttons = [];
names = [];
family = new Array();
canvas_margin_left = 0;
canvas_margin_top = 0;

canvas = '';//document.getElementById("canvas");
cxt = '';//canvas.getContext("2d");
canvas_top = '';//document.getElementById("canvas_top");
cxt_top = '';//canvas_top.getContext("2d");
line_width = new Array("0","1","1","1");
QIN_TREE_WIDTH = QIN_TREE_MIN_WIDTH;//canvas.clientWidth;
QIN_TREE_HEIGHT = 450;//(MEMBER_BLOCK_HEIGHT+RELATIVE_LINE_HEIGHT) * LEVEL - RELATIVE_LINE_HEIGHT + 10;
//QIN_TREE_HEIGHT = 1;//QIN_TREE_WIDTH;
// log("QIN_TREE_WIDTH: "+QIN_TREE_WIDTH);
child_num_level_1 =0;
child_num_level_2 =0;
child_num_level_3 =0;
horizon_child_num =0;
child_num_in_level = new Array(0,0,0,0);

function log(str)
{
    $("#msg1").html($("#msg1").html()+ str+"<br/>");
}
function pageX(elem) {//获取元素相对于整个文档的X位置的函数；
    var p = 0;
    while ( elem.offsetParent ) {
        p += elem.offsetLeft;
        elem = elem.offsetParent;
    }
    return p;
}
function pageY(elem){ //获取元素相对于整个文档的Y位置的函数；
    var p = 0;
    while ( elem.offsetParent ) {
        p += elem.offsetTop;
        elem = elem.offsetParent;
    }
    return p;
}
function getItem(array, e)
{
    // log("getItem");
    var mouse_x = e.pageX - canvas_margin_left;
    var mouse_y = e.pageY - canvas_margin_top;
    // search which member is hovered
    // log("will for");
    var find = false;
    // log("find = false");
    for(var i=0; i<array.length; i++)
    {
	// log("type: "+array[i].x1);
	if (mouse_x >= array[i].x1 && mouse_x <= array[i].x2 &&
	    mouse_y >= array[i].y1 && mouse_y <= array[i].y2)
	{
	    find = true;
	    break;
	}
    }
    // log("break");
    if (!find)
    {
	// log("return null");
	return null;
    }

    var a= array[i];
    return a;
}

function getRightestItem(array, e)
{
    // log("getItem");
    var mouse_x = e.pageX - canvas_margin_left;
    var mouse_y = e.pageY - canvas_margin_top;
    // search which member is hovered
    // log("will for");
    var find = 0;
    var right = mouse_x;
    
    // log("find = false");
    for(var i=0; i<array.length; i++)
    {
	// log("type: "+array[i].x1);
	if (mouse_y == array[i].y1 && right <= array[i].x2)
	{
	    find = i;
	    right = array[i].x2;
	}
    }
    // log("break");
    if (!find)
    {
	// log("return null");
	return null;
    }

    return array[find];
}

$(document).ready(function(){
    canvas_margin_left = pageX($("#family-tree")[0]);
    canvas_margin_top = pageY($("#family-tree")[0]);
});

// draw a member on a canvas
function drawMember(div, user, x, y, c)
{
    var figure = user.figureurl ? user.figureurl : 
	user.gender == 'male' ? MALE_FIGURE : FEMALE_FIGURE;
    var relative_type = c ? "blood-relative" : "in-law";
    $("<div class='member' style='position:absolute; left: "+x+"px; top:"+(y)+"px;'><a class='a-to-tree' title='"+user.name+"' href='/tree/index?userid="+user.id+"'><img class='figure-img' alt='"+user.realname+"' src='"+figure+"'/><a class='a-to-home "+relative_type+"' title='"+user.name.substring(0, NAME_LENGTH)+"' href='/users/home?userid="+user.id+"'>"+user.name.substring(0, NAME_LENGTH)+"</a></div>").appendTo(div);

    var ext = lteIE6 ? "gif" : "png";
    $("<a class='a-to-tree' title='"+user.name+"' href='/tree/index?userid="+user.id
	+"'><img class='figure-img' src='/Public/Img/figure-mask."+ext+"' style='position:absolute; left: "+x+"px; top:"+(y)+"px;'/></a>").appendTo(div);
}

// left x, left y
function getOverlap(x1, y1)
{
    var e = new Object();
    e.pageX = x1 + canvas_margin_left;
    e.pageY = y1 + canvas_margin_top;
    return getRightestItem(elements, e);
}

function lineTo(cxt, root_x, root_y, head_x, head_y, i)
{
    var ext = lteIE6 ? "gif" : "png";
    if (root_x > head_x)
    {
	$("<img src='/Public/Img/line2left."+ext+"' style='position: absolute; top:"+
	  (head_y-CHILD_POINT_PADDING-RELATIVE_LINE_HEIGHT)+"px; left:"+head_x+"px; width:"+
	  (root_x-head_x)+"px; height: "+(head_y-root_y)+"px; z-index:"+
	  i+"'/>")
	    .appendTo(cxt);
    }
    else if (root_x == head_x)
    {
	$("<img src='/Public/Img/line2mid."+ext+"' style='position: absolute; top:"+
	  (head_y-CHILD_POINT_PADDING-RELATIVE_LINE_HEIGHT)+"px; left:"+head_x+"px; width:1px; height: "+
	  (head_y-root_y)+"px;'/>")
	    .appendTo(cxt);
    }
    else
    {
	$("<img src='/Public/Img/line2right."+ext+"' style='position: absolute; top:"+
	  (head_y-CHILD_POINT_PADDING-RELATIVE_LINE_HEIGHT)+"px; left:"+root_x+"px; width:"+
	  (head_x-root_x)+"px; height: "+(head_y-root_y)+"px;'/>")
	    .appendTo(cxt);

	var point = '/Public/Img/child-point.png';
    }
    $("<img src='/Public/Img/child-point."+ext+"' style='position: absolute; top:"+
      (head_y-CHILD_POINT_PADDING-RELATIVE_LINE_HEIGHT+head_y-root_y-CHILD_RADIUS)+"px; left:"+(head_x-CHILD_RADIUS)+"px; '/>")
    	.appendTo(cxt);
}

drawed_nodes_num_in_level = new Array(0,0,0,0);
// 
function drawMemberTree(cxt, x1, y, x2, tree, level)
{
    // if mate exists
    if (tree.mates && tree.mates.length > 0)
    {
	if (level > 1)
	    var len = (tree.mates && tree.mates.length >= MAX_MATES) ?  MAX_MATES : 
	    ((tree.mates && tree.mates.length < MAX_MATES) ? tree.mates.length : 0);
	else
	    var len = tree.mates.length;
	//var len = child_num_in_level[level-1];//tree.children.length;

	var x_pad = x1 + (x2- x1- THUMB_WIDTH * (len+1) - THUMB_MARGIN_X * (len))/2;
	x_pad = x_pad > 0 ? x_pad : 0;

	if (obj = getOverlap(x_pad, y))
	{
	    x_pad = obj.x2 + THUMB_MARGIN_X;
	}
	// log("x_pad: "+x_pad);
	drawMember(cxt, tree, x_pad, y, 1);
	drawed_nodes_num_in_level[level]++;
	elements.push({id:tree.id, name:tree.name, gender:tree.gender, 
		       x1: x_pad, y1: y, x2: x_pad+THUMB_WIDTH, y2:y+THUMB_HEIGHT});	    
	names.push({id:tree.id, name:tree.name, gender:tree.gender, 
		    x1: x_pad, y1: y+THUMB_HEIGHT+NAME_MARGIN_TOP, x2: x_pad+THUMB_WIDTH, y2:y+THUMB_HEIGHT+NAME_MARGIN_TOP+NAME_HEIGHT});

	$.each(tree.mates, function(i, mate){
	    if(level > 1 && i >= MAX_MATES)
		return;
	    var xi = x_pad + (i+1)*(THUMB_WIDTH + THUMB_MARGIN_X);

	    if (obj = getOverlap(xi, y))
	    {
		xi = obj.x2 + THUMB_MARGIN_X;
	    }
	    drawMember(cxt, mate, xi, y, 0);
	    drawed_nodes_num_in_level[level]++;
	    elements.push({id:mate.id, name:mate.name, gender:mate.gender, 
			   x1: xi, y1: y, x2: xi+THUMB_WIDTH, y2:y+THUMB_HEIGHT});	    
	    names.push({id:mate.id, name:mate.name, gender:mate.gender, 
			x1: xi, y1: y+THUMB_HEIGHT+NAME_MARGIN_TOP, x2: xi+THUMB_WIDTH, y2:y+THUMB_HEIGHT+NAME_MARGIN_TOP+NAME_HEIGHT});

	});

    }
    else
    {
	var xm = x1 + (x2 - x1 - THUMB_WIDTH) / 2;
	if (obj = getOverlap(xm, y))
	{
	    xm = obj.x2 + THUMB_MARGIN_X;
	}
	drawMember(cxt, tree, xm, y, 1);
	drawed_nodes_num_in_level[level]++;
	// log("xm: "+xm);
	elements.push({id:tree.id, name:tree.name, 
		       gender:tree.gender,
		       x1: xm, y1: y, 
		       x2: xm+THUMB_WIDTH, y2:y+THUMB_HEIGHT});
	names.push({id:tree.id, name:tree.name, gender:tree.gender, 
		    x1: xm, y1: y+THUMB_HEIGHT+NAME_MARGIN_TOP, x2: xm+THUMB_WIDTH, y2:y+THUMB_HEIGHT+NAME_MARGIN_TOP+NAME_HEIGHT});

    }
    var root_x = (x1 + x2) / 2;
    var root_y = y + MEMBER_BLOCK_HEIGHT;

    // draw the children
    if (tree.children && tree.children.length>0)
    {
	// circle(cxt, root_x, root_y, PARENT_RADIUS, LINE_STYLE);
	var len = child_num_in_level[level+1];//tree.children.length;
	// var more_btn = false;
	var index = 0;
	$("<img src='/Public/Img/root-point.png' style='position: absolute; top:"+
	  (root_y-CHILD_POINT_PADDING-PARENT_RADIUS)+"px; left:"+(root_x-PARENT_RADIUS)+"px;'/>")
	    .appendTo(cxt);

	$.each(tree.children, function(i, subtree){
	    // if (more_btn)
	    // 	return;
	    // log(subtree.name);
	    var mates_num = (subtree.mates && subtree.mates.length >= MAX_MATES) ?  MAX_MATES : 
		((subtree.mates && subtree.mates.length < MAX_MATES) ? subtree.mates.length : 0);
	    
	    var child_width = ((x2-x1) / len) > (THUMB_WIDTH+THUMB_MARGIN_X) ? ((x2-x1) / len) : (THUMB_WIDTH+THUMB_MARGIN_X);
	    var child_x1 = x1 + index * child_width;
	    var head_y = y + MEMBER_BLOCK_HEIGHT + RELATIVE_LINE_HEIGHT;

	    // 后面有足够的空间画本行剩余的节点马？
	    var width_will_end_at = child_x1 + (len - drawed_nodes_num_in_level[level+1]) * (THUMB_WIDTH+THUMB_MARGIN_X);
	    if ( width_will_end_at > QIN_TREE_WIDTH)
	    {
	    	// child_x1 -= 1;
	    	// width_will_end_at = child_x1 + (len - drawed_nodes_num_in_level[level+1]) * (THUMB_WIDTH+THUMB_MARGIN_X);
		child_x1 = QIN_TREE_WIDTH - (len - drawed_nodes_num_in_level[level+1]) * (THUMB_WIDTH+THUMB_MARGIN_X);
	    }
	    if (child_x1 < 0)
		child_x1 = 0;

	    // 如果跟已有人物重合，则向后平移
	    // var obj = new Object();
	    if (obj = getOverlap(child_x1, head_y))
	    {
		// log('===================');
		child_x1 = obj.x2 + THUMB_MARGIN_X;
		// child_x2 = child_x1 + child_width;
		// head_x = (child_x1 + child_x2) / 2;
	    }

	    index += 1 + mates_num;
	    var child_x2 = child_x1 + (1 + mates_num) * child_width;
	    var head_x = (child_x1 + child_x2) / 2; // to the child, not the daughter in law

	    // 如果超出画布，则退出。
	    if (child_x1 > QIN_TREE_WIDTH)
		return;

	    // draw the subtree of this child
	    drawMemberTree(cxt, child_x1, head_y, child_x2, subtree, level+1);

	    // draw a line from root to this child
	    lineTo(cxt, root_x, root_y, head_x, head_y, i);
	});
    }
}

function init_canvas(tree)
{
    // adaptable width automatically
    get_children_num_in_level(tree, 1, true);
    for (var i in child_num_in_level)
    {
	if (VIEW_FROM_QQ_APP)
	    child_num_in_level[i] = child_num_in_level[i] > MAX_HORIZON_CHILD_NUM ? MAX_HORIZON_CHILD_NUM : child_num_in_level[i];
	horizon_child_num = child_num_in_level[i] > horizon_child_num ? child_num_in_level[i] : horizon_child_num;
    }

    var main_width = $("#main")[0].clientWidth;
    var canvas_width = (THUMB_WIDTH+THUMB_MARGIN_X) * horizon_child_num + 20;
    QIN_TREE_WIDTH = canvas_width < QIN_TREE_MIN_WIDTH ? QIN_TREE_MIN_WIDTH : 
	(canvas_width > QIN_TREE_WIDTH ? canvas_width : QIN_TREE_WIDTH);
    // QIN_TREE_WIDTH = QIN_TREE_WIDTH > (main_width-60) ? (main_width-60) : QIN_TREE_WIDTH;

    if (!VIEW_FROM_QQ_APP)
    {
	out_width = (QIN_TREE_WIDTH +20 )> MAX_FAMILY_BOX_WIDTH ? MAX_FAMILY_BOX_WIDTH : QIN_TREE_WIDTH;
	$("#out-of-family-tree").width(out_width+20);
    }
    else
	$("#out-of-family-tree").width(BODY_WIDTH_FROM_QQ-20);

    var aside_width = main_width - QIN_TREE_WIDTH - 90;
    aside_width = aside_width < ASIDE_MIN_WIDTH ? ASIDE_MAX_WIDTH : aside_width;
    aside_width = aside_width > ASIDE_MAX_WIDTH ? ASIDE_MAX_WIDTH : aside_width;
    $("#aside").width(aside_width);
    // $("#family-tree").width(QIN_TREE_WIDTH);
    // $("#family-tree").height(QIN_TREE_HEIGHT);

    if (QIN_TREE_WIDTH - $("#family-tree").width() > 10)
    {
	$("#family-tree").css("overflow-x", "scroll").css("overflow-y", "hidden");
    }
}
var uid = $("#userid").val();

if (window.sessionStorage && typeof JSON != 'undefined' && window.sessionStorage.getItem("user_"+uid))
{
    var tree = JSON.parse(window.sessionStorage.getItem("user_"+uid));
    init_canvas(tree[0]);
    drawMemberTree($("#family-tree"), 10, 10, QIN_TREE_WIDTH-10, tree[0], 1);
}
else
    $.getJSON("/tree/get_family_tree?userid="+uid,
	      function(tree){
		  // update the local storage
		  if (window.sessionStorage && typeof JSON != 'undefined')
	      	      window.sessionStorage.setItem("user_"+uid, JSON.stringify(tree));

		  init_canvas(tree[0]);

		  // draw the family tree
		  drawMemberTree($("#family-tree"), 10, 10, QIN_TREE_WIDTH-10, tree[0], 1);
	      });
